from functools import total_ordering
from models.ios_widget import model
from datetime import datetime, timedelta
from helpers.ios_widget import setting
from lib.qiniu_url_unixtime import qiniu_url_unixtime
import json
from functools import wraps
from lib.easy_redis import r as redis_client
import redis

tb_analysised_data = model.AnalysisUserWidgetList()
tb_analysis_view = model.AnalysisWidgetView()
tb_analysis_click = model.AnalysisWidgetClick()
tb_module = model.ComponentLibraryModuleList()
tb_analysis_complete_set = model.AnalysisWidgetCompleteSet()

# 默认连接本地 Redis 实例
# redis_client = redis.Redis(host='localhost', port=6379, db=0)


def get_analysis_data(start_date:datetime=None, end_date:datetime=None, skip:int=0, limit:int=10, search_code:str="click_rate_desc",n=1):
    if start_date and end_date:
        start_time = datetime(start_date.year, start_date.month, start_date.day)
        end_time = datetime(end_date.year, end_date.month, end_date.day, 23, 59, 59)
        res, count = get_data(start_date=start_time, end_date=end_time, search_code=search_code, skip=skip, limit=limit) 
    else:
        start_time = datetime.now() - timedelta(days=n)
        end_time = datetime.now() - timedelta(days=1)
        res, count = get_data(start_date=start_time, end_date=end_time, search_code=search_code, skip=skip, limit=limit) 
    return {
        'count': count,
        'list': res
    }


def get_data(start_date, end_date, skip, limit, search_code, cache_time=60*60*24):
    key = f"data:{start_date.strftime('%Y-%m-%d')}:{end_date.strftime('%Y-%m-%d')}"
    result = redis_client.get(key)
    if result:
        data_list = json.loads(result.decode('utf-8'))
    else:
        init_dict = search_data(start_date, end_date, tb_analysised_data, search_code=0)
        view_count_user_dict = search_data(start_date, end_date, tb_analysis_view, search_code=1)
        click_count_user_dict = search_data(start_date, end_date, tb_analysis_click, search_code=1)
        complete_set_count_user_dict = search_data(start_date, end_date, tb_analysis_complete_set, search_code=1)
        data_list = format_data(init_dict, view_count_user_dict, click_count_user_dict, complete_set_count_user_dict)
        redis_client.setex(key, cache_time, json.dumps(data_list)) # 缓存结果，并设置缓存时间
    res, count = sort_data(data_list=data_list, sort_code=search_code)
    res = res[skip:skip+limit]
    return res, count



def sort_data(data_list, sort_code:str): 
    sort_options = {
        'click_rate_desc': ('click_rate', True),
        'click_rate_asc': ('click_rate', False),
        'complete_set_rate_desc': ('complete_set_rate', True),
        'complete_set_rate_asc': ('complete_set_rate', False)
    }

    i, j = sort_options.get(sort_code, ('click_rate', True))
    data_list.sort(key=lambda x: x[i], reverse=j)
    count = len(data_list)
    return data_list, count


def search_data(start_time: datetime, end_time: datetime, mongo_collection, search_code:int=0):
    # 构造查询条件
    query_pipelint = [
        {
            '$match': {
                'atime': {
                    '$gte': start_time,
                    '$lte': end_time
                }
            }
        },
        {
            '$group': {  # 合并数据（oid为唯一）
                '_id': '$oid',
                'total_view_count': {'$sum': '$view_count'},
                'total_click_count': {'$sum': '$click_count'},
                'total_complete_set_count': {'$sum':'$complete_set_count'}
            }
        }
    ]
    unique_user_pipeline = [
        {
            '$match': {
                'atime': {
                    '$gte': start_time,
                    '$lte': end_time
                }
            }
        },
        {
            '$group': {
                '_id': {
                    'oid': '$oid',
                    'open_id': '$open_id'
                }
            }
        },
        {
            '$group': {
                '_id': '$_id.oid',
                'count': {'$sum': 1}
            }
        }
    ]
    r = {}  # 存储去重后的数据
    if search_code == 0:
        records = list(mongo_collection.aggregate(query_pipelint))
        for f in records:
            oid = f['_id']
            view_count = f['total_view_count']
            click_count = f['total_click_count']
            complete_set_count = f['total_complete_set_count']
            # 计算点击率、完成设置率，并添加到目标数据列表中
            click_rate = get_rate(click_count, view_count)
            complete_set_rate = get_rate(complete_set_count, click_count)

            data_dict = {}
            data_dict['view_count'] = view_count
            data_dict['click_count'] = click_count
            data_dict['complete_set_count'] = complete_set_count
            data_dict['click_rate'] = click_rate
            data_dict['complete_set_rate'] = complete_set_rate
            r[oid] = data_dict
    elif search_code == 1:
        records = list(mongo_collection.aggregate(unique_user_pipeline))
        for f in records:
            oid = f['_id']
            data_count = f['count']
            r[oid] = data_count
    return r


def format_data(init_count_dict:dict, view_user_dict: dict,  click_user_dict: dict,  complete_set_user_dict: dict) -> list:
    result_list = []
    for key in init_count_dict.keys():
        view_count_user = get_value(view_user_dict,key)
        click_count_user = get_value(click_user_dict,key) 
        complete_set_count_user = get_value(complete_set_user_dict,key)
        r = {}
        r['oid'] = str(key)
        r['view_count'] = f"{init_count_dict[key]['view_count']:<4} /&nbsp&nbsp{view_count_user:<4}"
        r['click_count'] = f"{init_count_dict[key]['click_count']:<4} /&nbsp&nbsp{click_count_user:<4}"
        r['complete_set_count'] = f"{init_count_dict[key]['complete_set_count']:<4} /&nbsp&nbsp{complete_set_count_user:<4}"
        r['click_rate'] = init_count_dict[key]['click_rate']
        r['complete_set_rate'] = init_count_dict[key]['complete_set_rate']

        result = tb_module.find_one({'_id': key})
        r['name'] = result['name']
        r['widget_type'] = result['widget_type']
        r['thumb_url'] = qiniu_url_unixtime(setting.QINIU_HOST, result.get('thumb_url', ''))
        result_list.append(r)       
    return result_list


def get_rate(up, down):
    if not down:
        return 0.0000
    r = up/down
    return float(f"{r:.4f}")


def get_value(dic, key):
    return dic[key] if key in dic else 0


if __name__ == "__main__":
    start_time = datetime(2023, 12, 19)
    end_time = datetime(2023, 12, 19)
    res = get_analysis_data(start_date=start_time,end_date=end_time)
    print(f'共{res["count"]}条数据')
    print(res['list'])

